/*

Copyright 2009 Nicola Dal Pont

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

package com.astoolkit.workflow
{
	import flash.events.IEventDispatcher;
	
	import mx.core.IFactory;
	import mx.core.IMXMLObject;
	import mx.rpc.Fault;
	
	[Event(
        name="started",
        type="com.astoolkit.workflow.WorkflowEvent")]
	[Event(
        name="initialize",
        type="com.astoolkit.workflow.WorkflowEvent")]
	[Event(
        name="warning",
        type="com.astoolkit.workflow.WorkflowEvent")]
	[Event(
        name="fault",
        type="com.astoolkit.workflow.WorkflowEvent")]
	[Event(
        name="completed",
        type="com.astoolkit.workflow.WorkflowEvent")]
	[Event(
        name="progress",
        type="com.astoolkit.workflow.WorkflowEvent")]
	[Event(
        name="prepare",
        type="com.astoolkit.workflow.WorkflowEvent")]
	
	public interface IWorkflowTask 
		extends IEventDispatcher, IMXMLObject
	{
		
		function get context() : IWorkflowContext;
		function set context( inContext : IWorkflowContext ) : void;
		
		function get status() : String;
		
		/**
		 * Whether to run this workflow asynchronously.
		 */ 
		function get async() : Boolean
			
		/**
		 * a description for this task.
		 * It can be used to give feedback on the currently running task.
		 */
		function get description() : String;
		function set description( inName : String ) : void;
		
		/**
		 * if false this task will be skipped
		 */
		[Inspectable(defaultValue="true", type="Boolean")]
		function get enabled() : Boolean;
		function set enabled( inEnabled : Boolean ) : void;
		
		/**
		 * instructs the wrapping worfklow on what to do
		 * if this task fails.
		 * Acceptable values are: ignore, abort, warn
		 * ignore: continues flow
		 * abort: the parent workflow fails too
		 * warn: continues flow but logs error 
		 */
		function get failurePolicy() : String;
		function set failurePolicy( inPolicy : String ) : void;
		
		/**
		 * the wrapping worfklow. Null for root workflow 
		 */
		function get parent() : IWorkflow;
		function set parent( inParent : IWorkflow ) : void;

		/**
		 * read only. returns the 0 to 1 progress of this task.
		 * A value of -1 means that this task won't provide progress information.
		 */
		function get currentProgress() : Number;
		function set currentProgress( inValue : Number ) : void;

		/**
		 * the number of milliseconds the wrapping workflow will wait
		 * before calling begin().
		 * Notice that prepare() will be called before this delay. 
		 */
		function get delay():int;
		function set delay( inDelay : int ) : void;

		function set delegate( inValue : IWorkflowDelegate ) : void;
		
		/**
		 * called when the root workflow completes.
		 * implementations should release any allocated resource
		 * or listener used during the whole task's lifetime
		 */
		function cleanUp() : void;
		
		/**
		 * this is the method a new task will always implement.
		 * It's where the task's async operations are fired.
		 * Once the task is complete it should call its delegate's 
		 * onComplete() or onFault(...) asyncronously, that is, not 
		 * in the begin() call stack.
		 */
		function begin( inRetain : Boolean = false ) : void;
			
				
		/**
		 * called by user defined code or by aborted wrapping workflow.
		 * implementations should take care of cancelling any pending async 
		 * operations or event listeners
		 */  
		function abort() : void;
		
		
		/**
		 * called by parent workflow when root workflow begins
		 * Users should not call this method directly.
		 */
		function initialize() : void;
		
		/**
		 * called by parent workflow before [pause + ] begin.
		 * If this task has state, this is the place to put code to 
		 * reset any value for next invocation.
		 * A "prepare" event must be dispatched first. 
		 * Listeners might perform dependency injection at this point.
		 */
		function prepare() : void;
		
		/**
		 * stops the whole workflow at this task until resume is called.
		 */
		function suspend() : void;
		
		/**
		 * resumes the whole workflow from the point where
		 * suspend() was called. Not necessarily this task.
		 * It might be any root workflow's children task.
		 */
		function resume() : void;
		
	}
}